package org.jacp.demo.io;

import java.io.IOException;
import java.io.InputStream;

public final class CombinedInputStream extends InputStream {
    private InputStream[] inputs;

    public CombinedInputStream(final InputStream in1, final InputStream in2) {
	inputs = new InputStream[] { in1, in2 };
    }

    @Override
    public int available() throws IOException {
	if (inputs.length == 0) {
	    return 0;
	}
	final int avail = inputs[0].available();
	if (avail != 0) {
	    return avail;
	}
	removeInput();
	return available();
    }

    private void removeInput() {
	try {
	    inputs[0].close();
	} catch (final IOException e) {
	    e.printStackTrace();
	}
	final InputStream[] newArray = new InputStream[inputs.length - 1];
	System.arraycopy(inputs, 1, newArray, 0, newArray.length);
	inputs = newArray;
    }

    @Override
    public void close() throws IOException {
	for (final InputStream input : inputs) {
	    input.close();
	}
	inputs = new InputStream[0];
    }

    @Override
    public boolean markSupported() {
	return false;
    }

    @Override
    public synchronized void reset() throws IOException {
    }

    @Override
    public synchronized void mark(final int readlimit) {
    }

    @Override
    public int read() throws IOException {
	if (inputs.length == 0) {
	    return -1;
	}
	final int k = inputs[0].read();
	if (k != -1) {
	    return k;
	}
	removeInput();
	return read();
    }

    @Override
    public int read(final byte[] b, final int off, final int len)
	    throws IOException {
	if (inputs.length == 0) {
	    return -1;
	}

	final int k = inputs[0].read(b, off, len);
	if (k != -1) {
	    return k;
	}
	removeInput();
	return read(b, off, len);
    }

    @Override
    public int read(final byte[] b) throws IOException {
	return read(b, 0, b.length);
    }

    @Override
    public long skip(final long n) throws IOException {
	if (inputs.length == 0) {
	    return -1;
	}

	long skipped = 0;
	while (skipped < n) {
	    final long t = inputs[0].skip(n - skipped);
	    if (t == -1) {
		removeInput();
		if (inputs.length == 0) {
		    return skipped;
		}
	    }
	    skipped += t;
	}
	return skipped;
    }
}
